// -*- C++ -*-
//
//  This file is part of Siena, a wide-area event notification system.
//  See http://www.inf.usi.ch/carzaniga/siena/
//
//  Authors: Antonio Carzaniga
//  See the file AUTHORS for full details. 
//
//  Copyright (C) 2001-2003 University of Colorado
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
//  USA, or send email to one of the authors.
//
//
// $Id: string_index.h,v 1.16 2010-03-11 15:16:42 carzanig Exp $
//
#ifndef STRING_INDEX_H
#define STRING_INDEX_H

#include "siena/types.h"
#include "siena/forwarding.h"
#include "siena/allocator.h"
#include "siena/fwdtable.h"

namespace siena {

typedef unsigned char	mask_t;

class PTSTNode {
public:
    void *		data;
			PTSTNode(int, PTSTNode *, unsigned char) throw();

    int			c;
    PTSTNode *		up;
    PTSTNode *		left;
    PTSTNode *		middle;
    PTSTNode *		right;
    mask_t		mask;
};

enum PartialResult {
    Found_Partial,
    Found_Complete,
    Not_Found
};

/** descriptor of a complete match in a <code>StringIndex</code> **/
class SICompleteDescr {
public:
    ConstraintType *		eq;
    ConstraintType *		ne;
    ConstraintType *		lt;
    ConstraintType *		gt;
    ConstraintType *		sf;
    SICompleteDescr *		next_lt;
    SICompleteDescr *		next_gt;
};

/** descriptor of a partial match in a <code>StringIndex</code> **/
struct SIPartialDescr {
    ConstraintType *		pf;
    ConstraintType *		ss;
};

/** index of string constraints.
 *
 *  This data structure supports <em>equals</em>, <em>less-than</em>,
 *  <em>greater-than</em>, <em>prefix</em>, <em>suffix</em>, and
 *  <em>substring</em> constraints on strings
 **/
class StringIndex {
public:
			StringIndex() throw();

    void		consolidate(FTAllocator &) throw();
    ConstraintType *	add_eq(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_ne(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_lt(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_gt(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_pf(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_sf(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_ss(const string_t & v, FTAllocator &) throw();
    ConstraintType *	add_re(const string_t & v, FTAllocator &)
	throw(bad_constraint);
    ConstraintType *	add_any(FTAllocator &) throw();

    bool		match(const string_t & v, 
			      CProcessor & p) const throw();

private:
    PTSTNode *		insert_complete(const char *, const char *, 
					FTAllocator &,
					const mask_t) throw();
    PTSTNode *		insert_partial(const char * s, const char * end,
				       FTAllocator & a,
				       const mask_t) throw();
    bool		tst_match(const string_t & v, 
			          CProcessor & p) const throw();
    PTSTNode * root;
    ConstraintType * any_value;
};

inline PTSTNode::PTSTNode(int xc, PTSTNode * xup, mask_t m) throw()
    : data(0), c(xc), up(xup), left(0), middle(0), right(0), mask(m) {}

inline StringIndex::StringIndex() throw() : root(0), any_value(0) {}

} // end namespace siena

#endif
